﻿using RQX.Common.Web.Config;
using RQX.Common.Web.Tools;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Loader;

namespace RQX.Common.Web.Web.Container
{
    /// <summary>
    /// 插件反射互相调用类
    /// </summary>
    public class ApolloPlugReflection
    {
        private static ConcurrentDictionary<string, ApolloPlug> PlugDic = new ConcurrentDictionary<string, ApolloPlug>();
        static ApolloPlugReflection()
        {
            var baseList = AppConfigurtaion.GetAllConfigValue();
            var dllList = baseList.Where(k => k.Key.ContainsAll($"{GlobalConfig.PlugDic}:", ":DllName"));
            var dbList = baseList.Where(k => k.Key.ContainsAll($"{GlobalConfig.PlugDic}:", ":DbContext"));

            var path = AppConfigurtaion.GetConfigValue(GlobalConfig.PlugPath);
            var files = Directory.GetFiles(path);

            foreach (var dllName in dllList)
            {
                var file = files.Find(k => k.Contains($"{dllName.Value}.dll"));
                if (file != null)
                {
                    using var fs = new FileStream(file, FileMode.Open, FileAccess.Read);
                    var assembly = new AssemblyLoadContext(Guid.NewGuid().ToString("N"), true).LoadFromStream(fs);
                    var plugName = dllName.Key.Split(':')[2];
                    var dbName = dbList.Find(k => k.Key.Equals($"{GlobalConfig.PlugDic}:{plugName}:DbContext")).Value;
                    PlugDic.TryAdd(plugName, new ApolloPlug(assembly));
                }
            }
        }

        public static ApolloPlug GetPlug(string name)
        {
            if (PlugDic.ContainsKey(name))
            {
                return PlugDic.GetValueOrDefault(name);
            }
            else
            {
                return null;
            }
        }

        //public object this[string plugName,string className] => throw new NotImplementedException();


    }
}
